// @algorithm @lc id=437 lang=cpp 
// @title path-sum-iii


// @test([10,5,-3,3,2,null,11,3,-2,null,1],8)=3
// @test([5,4,8,11,null,13,4,7,2,null,null,5,1],22)=3
class Solution {
public:
    int pathSum(TreeNode* root, int targetSum) {
        int ans = 0;
        unordered_map<int,int> prePaths; // preSum => pathCount
        prePaths[0] = 1;
        function<void(TreeNode*,int)> dfs = [&](TreeNode *cur, int sum){
            if(!cur) return;
            sum += cur->val;
            auto it = prePaths.find(sum-targetSum);
            if(it != prePaths.end())
                ans += it->second;
            ++ prePaths[sum];
            dfs(cur->left, sum);
            dfs(cur->right, sum);
            -- prePaths[sum];
        };
        dfs(root, 0);
        return ans;
    }
};
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */